<template>
  <el-card>
    <!-- 工具栏 -->
    <div class="toolbar">
      <el-input
        v-model="filters.name"
        placeholder="标签名称"
        clearable
        @clear="onSearch"
        @keyup.enter="onSearch"
        class="toolbar-item"
        ><template #prefix>
          <el-icon><Search /></el-icon> </template
      ></el-input>
      <el-select
        v-model="filters.status"
        placeholder="状态"
        clearable
        @change="onSearch"
        class="toolbar-item"
        style="width: 150px"
      >
        <el-option label="启用" :value="1" />
        <el-option label="禁用" :value="0" />
      </el-select>
      <el-button type="primary" size="small" :icon="Plus" @click="openDialog()"
        >新增</el-button
      >
      <el-button
        type="danger"
        size="small"
        :icon="Delete"
        :disabled="!multiple.length"
        @click="onBatchDelete"
        >批量删除</el-button
      >
      <el-button size="small" @click="downloadTemplate">下载模板</el-button>
      <el-upload :before-upload="beforeUpload" :show-file-list="false">
        <el-button size="small">导入</el-button>
      </el-upload>
      <el-button size="small" @click="onExport">导出</el-button>
    </div>

    <!-- 表格 -->
    <el-table
      v-loading="loading"
      :data="list"
      stripe
      @selection-change="multiple = $event"
      style="width: 100%"
    >
      <el-table-column align="center" type="selection" width="50" />
      <el-table-column align="center" prop="id" label="ID" width="70" />
      <el-table-column align="center" prop="name" label="标签名称" />
      <el-table-column align="center" label="状态" width="240">
        <template #default="{ row }">
          <div class="status-cell">
            <span v-if="row.status === 0" class="status-label inactive"
              >禁用</span
            >
            <el-switch
              v-model="row.status"
              :active-value="1"
              :inactive-value="0"
              @change="(val) => onToggleStatus(row, val)"
              size="small"
            />
            <span v-if="row.status === 1" class="status-label active"
              >启用</span
            >
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="createAt" label="创建时间" width="160" />
      <el-table-column prop="updateAt" label="更新时间" width="160" />
      <el-table-column label="操作" width="160" fixed="right">
        <template #default="{ row }">
          <div class="action-btns">
            <el-button
              type="primary"
              circle
              :icon="Edit"
              @click="openDialog(row)"
            />
            <el-button
              circle
              type="danger"
              :icon="Delete"
              @click="onDelete(row)"
            />
          </div>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        background
        layout="prev, pager, next, jumper, sizes, total"
        :page-size="pageSize"
        :current-page="pageNum"
        :page-sizes="[10, 20, 50]"
        :total="total"
        @current-change="onPageChange"
        @size-change="onSizeChange"
      />
    </div>

    <!-- 新增/编辑 弹窗 -->
    <el-dialog :title="dialogTitle" v-model="dialogVisible">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="80px">
        <el-form-item label="标签名称" prop="name">
          <el-input v-model="form.name" autocomplete="off" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="onSubmit"
          >确定</el-button
        >
      </template>
    </el-dialog>
  </el-card>
</template>
  
  <script setup>
import { ref, reactive, onMounted, nextTick } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import {
  pageTags,
  addTag,
  updateTag,
  deleteTags,
  updateTagStatus,
  exportTags,
  downloadTagTemplate,
  importTags,
} from "@/api/tags";
import { Search, Plus, Delete, Edit } from "@element-plus/icons-vue";

// 查询参数
const filters = reactive({
  name: "",
  status: null,
});

// 列表状态
const loading = ref(false);
const list = ref([]);
const total = ref(0);
const pageNum = ref(1);
const pageSize = ref(10);
const multiple = ref([]);

// 弹窗状态
const dialogVisible = ref(false);
const isCreate = ref(true);
const dialogTitle = ref("新增标签");
const form = reactive({ id: null, name: "" });
const formRef = ref(null);
const saving = ref(false);
// 初始化标志
const initializing = ref(false);

// 校验规则
const rules = {
  name: [{ required: true, message: "请输入标签名称", trigger: "blur" }],
};

// 拉取列表
async function fetchList() {
  initializing.value = true;
  loading.value = true;
  try {
    const res = await pageTags({
      pageNum: pageNum.value,
      pageSize: pageSize.value,
      ...filters,
    });
    list.value = res.data.items;
    total.value = res.data.total;
    await nextTick();
    initializing.value = false;
  } finally {
    loading.value = false;
  }
}

// 分页回调
function onPageChange(p) {
  pageNum.value = p;
  fetchList();
}
function onSizeChange(s) {
  pageSize.value = s;
  pageNum.value = 1;
  fetchList();
}

// 搜索
function onSearch() {
  pageNum.value = 1;
  fetchList();
}

// 新增/编辑
function openDialog(row) {
  if (row) {
    isCreate.value = false;
    dialogTitle.value = "编辑标签";
    form.id = row.id;
    form.name = row.name;
  } else {
    isCreate.value = true;
    dialogTitle.value = "新增标签";
    form.id = null;
    form.name = "";
  }
  dialogVisible.value = true;
}

// 提交表单
function onSubmit() {
  formRef.value.validate((valid) => {
    if (!valid) return;
    saving.value = true;
    const fn = isCreate.value
      ? addTag({ name: form.name })
      : updateTag({ id: form.id, name: form.name });

    fn.then(() => {
      ElMessage.success(isCreate.value ? "新增成功" : "更新成功");
      dialogVisible.value = false;
      fetchList();
    }).finally(() => (saving.value = false));
  });
}

// 单条删除
function onDelete(row) {
  ElMessageBox.confirm("确认删除该标签？", "提示", { type: "warning" })
    .then(() => deleteTags([row.id].join(",")))
    .then(() => {
      ElMessage.success("删除成功");
      fetchList();
    });
}

// 批量删除
function onBatchDelete() {
  ElMessageBox.confirm("确认删除选中的标签？", "提示", { type: "warning" })
    .then(() => {
      return deleteTags(multiple.value.map((i) => i.id).join(","));
    })
    .then(() => {
      ElMessage.success("批量删除成功");
      multiple.value = [];
      fetchList();
    });
}

// 启用/禁用 切换
function onToggleStatus(row, newStatus) {
  if (initializing.value) return;
  updateTagStatus(row.id, newStatus)
    .then(() => {
      ElMessage.success("状态更新成功");
    })
    .catch(() => {
      // 如果失败，回滚到旧状态
      row.status = newStatus === 1 ? 0 : 1;
    });
}

// 导出 Excel
function onExport() {
  exportTags().then((res) => {
    const url = window.URL.createObjectURL(new Blob([res]));
    const a = document.createElement("a");
    a.href = url;
    a.download = "标签列表.xlsx";
    a.click();
    window.URL.revokeObjectURL(url);
  });
}

// 下载模板
function downloadTemplate() {
  downloadTagTemplate().then((res) => {
    const url = window.URL.createObjectURL(new Blob([res]));
    const a = document.createElement("a");
    a.href = url;
    a.download = "标签导入模板.xlsx";
    a.click();
    window.URL.revokeObjectURL(url);
  });
}

// 导入前校验 & 调用
function beforeUpload(file) {
  importTags(file).then(() => {
    ElMessage.success("导入成功");
    fetchList();
  });
  return false; // 阻止自动上传
}

// 初始化
onMounted(fetchList);
</script>
  
  <style scoped>
.el-card {
  padding: 32px 16px 24px 16px;
  background: linear-gradient(135deg, #f8fafc 0%, #f0f4f8 100%);
  border-radius: 18px;
  box-shadow: 0 6px 32px 0 rgba(80,120,200,0.08);
  min-height: 90vh;
  transition: box-shadow 0.3s;
}
.toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  margin-bottom: 24px;
  align-items: center;
  background: rgba(255,255,255,0.85);
  border-radius: 14px;
  box-shadow: 0 2px 12px 0 rgba(80,120,200,0.06);
  padding: 18px 18px 10px 18px;
  animation: fadeInDown 0.7s;
}
@keyframes fadeInDown {
  from { opacity: 0; transform: translateY(-20px); }
  to { opacity: 1; transform: none; }
}
.toolbar-item {
  width: 180px;
  min-width: 120px;
  transition: box-shadow 0.2s, border-color 0.2s;
}
.toolbar-item .el-input__wrapper,
.toolbar-item .el-select__wrapper {
  border-radius: 8px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.04);
}
.toolbar-item .el-input__wrapper:hover,
.toolbar-item .el-select__wrapper:hover {
  border-color: #6c8cff;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
}
.el-button[type="primary"] {
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  border: none;
  color: #fff;
  font-weight: 500;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
  transition: background 0.2s, box-shadow 0.2s;
}
.el-button[type="primary"]:hover {
  background: linear-gradient(90deg, #88e0ef 0%, #6c8cff 100%);
  color: #fff;
}
.el-button[type="danger"] {
  background: linear-gradient(90deg, #ff6c6c 0%, #ffb88c 100%);
  border: none;
  color: #fff;
  font-weight: 500;
  box-shadow: 0 2px 8px 0 rgba(255,108,108,0.10);
  transition: background 0.2s, box-shadow 0.2s;
}
.el-button[type="danger"]:hover {
  background: linear-gradient(90deg, #ffb88c 0%, #ff6c6c 100%);
  color: #fff;
}
.action-btns {
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 14px;
  min-width: 100px;
}
.el-table {
  border-radius: 14px;
  overflow: hidden;
  background: rgba(255,255,255,0.98);
  box-shadow: 0 2px 16px 0 rgba(80,120,200,0.07);
  animation: fadeIn 0.7s;
}
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.el-table th {
  background: linear-gradient(90deg, #f0f4ff 0%, #f8fafc 100%);
  color: #4a5a7a;
  font-weight: 600;
  font-size: 15px;
}
.el-table tr {
  transition: background 0.2s;
}
.el-table tr:hover {
  background: #eaf3ff !important;
}
.el-table .el-table__row.selected {
  background: #d6e4ff !important;
}
.el-table .el-button {
  border-radius: 50%;
  font-size: 18px;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 2px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.08);
  transition: background 0.2s, transform 0.2s;
}
.el-table .el-button:hover {
  background: linear-gradient(90deg, #6c8cff 0%, #88e0ef 100%);
  color: #fff;
  transform: scale(1.12);
}
.status-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
}
.status-label {
  padding: 2px 12px;
  border-radius: 12px;
  font-size: 13px;
  font-weight: 500;
  background: #f5f7fa;
  color: #606266;
  margin: 0 6px;
  transition: background 0.2s, color 0.2s;
}
.status-label.active {
  background: #e6f9ec;
  color: #67c23a;
}
.status-label.inactive {
  background: #fff0f0;
  color: #f56c6c;
}
.pagination {
  text-align: center;
  margin-top: 24px;
}
.el-pagination {
  border-radius: 10px;
  background: rgba(255,255,255,0.85);
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.06);
  padding: 8px 16px;
}
.el-dialog {
  border-radius: 18px !important;
  box-shadow: 0 8px 40px 0 rgba(80,120,200,0.18) !important;
  animation: fadeInUp 0.5s;
}
@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(40px); }
  to { opacity: 1; transform: none; }
}
.el-dialog__header {
  font-size: 22px;
  font-weight: 700;
  color: #3a4a6a;
  letter-spacing: 1px;
}
.el-dialog__footer {
  background: #f8fafc;
  border-radius: 0 0 18px 18px;
  padding: 18px 24px;
}
.el-form-item__label {
  font-weight: 600;
  color: #3a4a6a;
  font-size: 15px;
}
.el-form-item .el-input__wrapper,
.el-form-item .el-select__wrapper {
  border-radius: 8px;
  box-shadow: 0 1px 4px 0 rgba(80,120,200,0.04);
  transition: box-shadow 0.2s, border-color 0.2s;
}
.el-form-item .el-input__wrapper:focus-within,
.el-form-item .el-select__wrapper:focus-within {
  border-color: #6c8cff;
  box-shadow: 0 2px 8px 0 rgba(80,120,200,0.10);
}
/* 响应式 */
@media screen and (max-width: 1024px) {
  .el-card {
    padding: 8px 2px 12px 2px;
  }
  .toolbar {
    flex-direction: column;
    gap: 10px;
    padding: 12px 8px 6px 8px;
  }
  .action-btns {
    min-width: 80px;
  }
  .el-table th, .el-table td {
    font-size: 13px;
  }
}
@media screen and (max-width: 768px) {
  .el-card {
    padding: 2px 0 6px 0;
    min-height: unset;
  }
  .toolbar {
    flex-direction: column;
    gap: 8px;
    padding: 8px 2px 4px 2px;
  }
  .toolbar-item {
    min-width: 90px;
    width: 100%;
  }
  .el-table th, .el-table td {
    font-size: 12px;
    padding: 4px 2px;
  }
  .el-dialog {
    width: 98vw !important;
    min-width: unset;
    padding: 0;
  }
}
</style>
  